<script setup>
import { toRefs, ref, onMounted, onBeforeUnmount, reactive, h, markRaw } from 'vue';
import { useRoute } from 'vue-router';
import { ElTooltip } from 'element-plus';
import CompassIcon from '@/assets/images/base-map/compass-icon.png';
import IconMinusCircle from '@/assets/images/base-map/icon-minus-circle.png';
import IconPlusCircle from '@/assets/images/base-map/icon-plus-circle.png';
import JuanLianIcon from '@/assets/images/base-map/juanlian.png';
import PositionIcon from '@/assets/images/base-map/position-icon.png';
import FenGeIcon from '@/assets/images/base-map/qeige.png';
import RulerIcon from '@/assets/images/base-map/ruler-icon.png';
import To3dIcon from '@/assets/images/base-map/to3d-icon.png';
import { useMapStore } from '@/stores';
import { DEFAULT_MAP_STATE } from '@/utils/map-helper';
import {
  MAP_2D_INIT,
  MapBoxFlyTo,
  MapBoxMagnifyZoom,
  MapBoxReduceZoom,
  mapTo3d,
  REMOVE_2D_MAP,
} from '@/utils/map-utils';
import { useMapScale } from '@/utils/useMapScale';
import MapAttribute from './MapAttribute/MapAttributeIndex.vue';
import MapBaseLayer from './MapBaseLayer/MapBaseLayerIndex.vue';
import MapBufferAnalysis from './MapBufferAnalysis/IndexBase.vue';
import MapCompare from './MapCompare/MapCompareIndex.vue';
import MapCoverAnalysis from './MapCoverAnalysis/MapCoverAnalysisIndex.vue';
import MapCutting from './MapCutting/MapCuttingIndex.vue';
import MapMeasure from './MapMeasure/MapMeasureIndex.vue';
import MapPoints from './MapPoints/MapPointsIndex.vue';
import MapAttributeQuery from './MapResultInfo/MapAttributeQuery.vue';
import MapQueryResultPolygon from './MapResultInfo/MapQueryResultPolygon.vue';
import MapTermingQuery from './MapTermingQuery/MapTermingQueryIndex.vue';
import MapThermalAnalysis from './MapThermalAnalysis/MapThermalAnalysisIndex.vue';
import SvgIconIndex from './SvgIconIndex.vue';

const props = defineProps({
  mapId: {
    type: String,
    default: '',
  },
  mapRoles: {
    type: Array,
    default: () => [],
  },
  toolbarPosition: {
    type: String,
    default: '0.9375rem',
  },
  toolbarRight: {
    type: String,
    default: '5.3125rem',
  },
  plugins: {
    type: Array,
    default: () => [],
  },
  mapLoadCallBack: {
    type: Function,
    default: () => {},
  }, // 地图初始化后加载回调函数 会传递map实例
  compareDataRequest: {
    type: Function,
    default: async () => [],
  }, // 用于获取数据对比数据
});
const { mapId, mapRoles, toolbarPosition, toolbarRight } = toRefs(props);

const emit = defineEmits(['mapPluginCheckChange']);

let map2D = null;

const { scale } = useMapScale();
const mapStore = useMapStore();
const resultFeatures = ref({});

const route = useRoute();
const mapTools = ref([]);
const mapToolsTop = ref([]);

let routeValue = route.query;

const mapZoom = ref(DEFAULT_MAP_STATE.zoom);
const showObject = reactive({
  isMeasure: false, //当前是否开启测量
  showLayer: false, //当前是否显示图层
  isCompare: false, //是否开启卷帘功能
  isCutting: false, //当前开启数据切割
  isAttribute: false, //是否开启属性查询
  isAnalysisShow: false, //是否开启分析
  isTerming: false, //是否开启条件查询功能
  isHeatMap: false, //是否开启热力图
  isCoverMap: false, //是否开启占地分析
  resultFeaturesShow: false, //是否显示属性查询结果(单数据)
  resultFeaturesPolygonShow: false, //是否显示属性查询结果(多数据)
  isBuffer: false, //缓冲区
});

// 属性查询
const MapAttributeBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '属性查询',

        onClick: () => handleChangeIsAttribute(!showObject.isAttribute),
      },
      [
        h(SvgIconIndex, {
          iconClass: '属性查询',
          size: '20',
          class: 'cursor-pointer',
          title: '属性查询',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 条件查询
const MapTermingBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '条件查询',

        onClick: () => handleChangeIsTerm(!showObject.isTerming),
      },
      [
        h(SvgIconIndex, {
          iconClass: '条件查询',
          size: '20',
          class: 'cursor-pointer',
          title: '条件查询',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};
// 热力图分析
const MapHeatBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '热力图分析',
        onClick: () => handleChangeIsHeatMap(!showObject.isHeatMap),
      },
      [
        h(SvgIconIndex, {
          iconClass: '热力图分析',
          size: '20',
          class: 'cursor-pointer',
          title: '热力图分析',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 占地分析
const MapCoverBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '占地分析',
        onClick: () => handleChangeIsCoverMap(!showObject.isCoverMap),
      },
      [
        h(SvgIconIndex, {
          iconClass: '占地分析',
          size: '20',
          class: 'cursor-pointer',
          title: '占地分析',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 缓冲区分析
const MapCHangeIsBufferBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '缓冲区分析',
        onClick: () => handleCHangeIsBuffer(),
      },
      [
        h(SvgIconIndex, {
          iconClass: '缓冲区分析',
          size: '20',
          class: 'cursor-pointer',
          title: '缓冲区分析',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 数据切割
const MapCuttingBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: '数据切割',
        onClick: () => handleChangeIsCutting(!showObject.isCutting),
      },
      [
        h('img', {
          src: FenGeIcon,
          alt: '数据切割',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};
// 卷帘
const MapCompareBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: showObject.isCompare ? '关闭卷帘' : '开启卷帘',
        onClick: () => handleChangeIsCompare(),
      },
      [
        h('img', {
          src: JuanLianIcon,
          alt: '卷帘',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};

// 测量工具
const MapMeasureBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: showObject.isMeasure ? '关闭测量' : '开启测量',
        onClick: () => handleChangeIsMeasure(),
      },
      [
        h('img', {
          src: RulerIcon,
          alt: '测量',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};

// 底图切换
const MapBaseLayerBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '图层',
        onClick: () => handleChangeIsBaseLayer(),
      },
      [
        h(SvgIconIndex, {
          iconClass: '底图切换',
          size: '20',
          class: 'cursor-pointer',
          title: '底图切换',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 二三维切换
const Map3DBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: '二三维切换',
        onClick: () => handle3DMode(),
      },
      [
        h('img', {
          src: To3dIcon,
          alt: '二三维切换',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};

// 初始化位置
const initPosition = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: '初始化视角',
        onClick: () => initializationPerspective(1),
      },
      [
        h('img', {
          src: CompassIcon,
          alt: '初始化视角',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};

// 当前位置
const currentPosition = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: '当前位置',
        onClick: () => initializationPerspective(2),
      },
      [
        h('img', {
          src: PositionIcon,
          alt: '当前位置',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};
// 地图Zoom
const mapControlZoom = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item-changesize',
      },
      [
        h('img', {
          src: IconPlusCircle,
          alt: '放大',
          title: '放大',
          style: {
            width: '1.5rem',
            height: '1.5rem',
          },
          onClick: () => MapBoxMagnifyZoom(),
        }),
        h(
          'div',
          {
            title: '级别',
            style: {
              color: 'rgba(201, 226, 250, 1)',
              backgroundColor: 'rgba(57, 115, 136,0.7)',
              width: '3.125rem',
              height: '3.125rem',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            },
          },
          mapZoom.value,
        ),
        h('img', {
          src: IconMinusCircle,
          title: '缩小',
          style: {
            width: '1.5rem',
            height: '1.5rem',
          },
          onClick: () => MapBoxReduceZoom(),
        }),
      ],
    );
  },
};

onMounted(() => {
  setTimeout(() => {
    if (!map2D) {
      map2D = MAP_2D_INIT(mapId.value);

      getMapRoles();
      MapTools();
      //   放大缩小
      map2D.on('zoom', function () {
        mapZoom.value = map2D.getZoom().toFixed(0);
      });

      window.addEventListener('resize', resize2D);
    }
  }, 100);
});

const getMapRoles = () => {
  mapTools.value = [
    {
      role: '属性查询',
      component: markRaw(MapAttributeBtn),
    },
    {
      role: '条件查询',
      component: markRaw(MapTermingBtn),
    },
    {
      role: '热力图分析',
      component: markRaw(MapHeatBtn),
    },
    {
      role: '占地分析',
      component: markRaw(MapCoverBtn),
    },
    {
      role: '缓冲区分析',
      component: markRaw(MapCHangeIsBufferBtn),
    },
    {
      role: '数据切割',
      component: markRaw(MapCuttingBtn),
    },
    {
      role: '卷帘',
      component: markRaw(MapCompareBtn),
    },
    {
      role: '测量',
      component: markRaw(MapMeasureBtn),
    },
    {
      role: '底图切换',
      component: markRaw(MapBaseLayerBtn),
    },
    {
      role: '二三维切换',
      component: markRaw(Map3DBtn),
    },
  ];
};

// 工具栏
const MapTools = () => {
  mapToolsTop.value = [
    {
      role: '初始化位置',
      component: markRaw(initPosition),
    },
    {
      role: '当前位置',
      component: markRaw(currentPosition),
    },
    {
      role: 'zoom',
      component: markRaw(mapControlZoom),
    },
  ];
};

function resize2D() {
  map2D?.resize();
}

//初始化视角
const initializationPerspective = async (type) => {
  if (type == 2) {
    if (JSON.parse(sessionStorage.getItem('CurrentPosition')) !== null) {
      let currentPosition = JSON.parse(sessionStorage.getItem('CurrentPosition'));

      MapBoxFlyTo([currentPosition.Longitude, currentPosition.Latitude], DEFAULT_MAP_STATE.zoom);
    } else {
      MapBoxFlyTo([DEFAULT_MAP_STATE.longitude, DEFAULT_MAP_STATE.latitude], DEFAULT_MAP_STATE.zoom);
    }
  } else {
    MapBoxFlyTo([DEFAULT_MAP_STATE.longitude, DEFAULT_MAP_STATE.latitude], DEFAULT_MAP_STATE.zoom);
  }
};

// 切换三维
const handle3DMode = () => {
  mapTo3d(mapStore.mode);
};

// 测量
const handleChangeIsMeasure = () => {
  showObject.isMeasure = !showObject.isMeasure;

  if (showObject.showLayer) {
    showObject.showLayer = false;
  }

  showObject.isCutting = false;
  showObject.isAttribute = false;
};

// 设置想要设置的状态
const changeShowUtil = (targetKey, boolean) => {
  emit('mapPluginCheckChange', targetKey, boolean);

  for (const key in showObject) {
    if (Object.hasOwnProperty.call(showObject, key)) {
      showObject[key] = boolean && key === targetKey;
    }
  }
};

// 缓冲区
const handleCHangeIsBuffer = () => {
  changeShowUtil('isBuffer', !showObject.isBuffer);
};

// 卷帘
const handleChangeIsCompare = () => {
  changeShowUtil('isCompare', !showObject.isCompare);
};

// 数据切割
const handleChangeIsCutting = (type) => {
  changeShowUtil('isCutting', type);
};

// 属性查询
const handleChangeIsAttribute = (type) => {
  changeShowUtil('isAttribute', type);
};

// 热力图分析
const handleChangeIsHeatMap = (type) => {
  changeShowUtil('isHeatMap', type);
};

// 占地分析
const handleChangeIsCoverMap = (type) => {
  changeShowUtil('isCoverMap', type);
};

// 条件查询
const handleChangeIsTerm = (type) => {
  changeShowUtil('isTerming', type);
};

// 底图
const handleChangeIsBaseLayer = () => {
  changeShowUtil('showLayer', !showObject.showLayer);
};

// 关闭属性查询窗口
const handleCloseQueryLayer = () => {
  resultFeatures.value = {};
  showObject.resultFeaturesShow = false;
  showObject.resultFeaturesPolygonShow = false;
};

// 获取相关属性数据
const handleQueryInfo = (item, checked_layer, type) => {
  if (type == '属性查询') {
    resultFeatures.value = item;

    setTimeout(() => {
      if (Object.keys(item)?.length) {
        checked_layer == 'spatial_point'
          ? (showObject.resultFeaturesShow = true)
          : checked_layer == 'spatial_polygon'
          ? (showObject.resultFeaturesPolygonShow = true)
          : '';
      } else {
        checked_layer == 'spatial_point'
          ? (showObject.resultFeaturesShow = false)
          : checked_layer == 'spatial_polygon'
          ? (showObject.resultFeaturesPolygonShow = false)
          : '';
      }
    }, 0);
  }
};

defineExpose({
  changeShowUtil,
});

onBeforeUnmount(() => {
  mapStore.RESET();
  window.removeEventListener('resize', resize2D);
  REMOVE_2D_MAP();
  map2D = null;
});
</script>
<template>
  <div id="map-root" class="map-root relative h-full w-full">
    <!-- 放大缩小初始位置工具 -->
    <div :class="`map-tool-top`" :style="{ right: toolbarPosition }">
      <div v-for="(tool, index) in mapToolsTop" :key="index">
        <component :is="tool.component" v-if="mapRoles.includes(tool.role)" />
      </div>
    </div>
    <div v-for="(tool, index) in props.plugins" :key="index">
      <ElTooltip class="box-item" effect="customized" :content="tool.role" placement="left">
        <component :is="tool.component" />
      </ElTooltip>
    </div>
    <div :class="`map-tool-bottom`" :style="{ right: toolbarPosition }">
      <!-- 工具栏(权限)-->
      <div v-for="(tool, index) in mapTools" :key="index">
        <ElTooltip class="box-item" effect="customized" :content="tool.role" placement="left">
          <component :is="tool.component" v-if="mapRoles.includes(tool.role)" />
        </ElTooltip>
      </div>
    </div>

    <!-- 底图 -->
    <MapBaseLayer
      v-if="showObject.showLayer"
      :toolbar-right="toolbarRight"
      @handle-change-is-base-layer="handleChangeIsBaseLayer"
    />
    <!-- 条件查询 -->
    <MapTermingQuery
      v-if="showObject.isTerming"
      :route-value="routeValue"
      :toolbar-right="toolbarRight"
      :map-id="mapId"
      @terming-close="() => handleChangeIsTerm(false)"
    />
    <!-- 属性查询 -->
    <MapAttribute
      v-if="showObject.isAttribute"
      :route-value="routeValue"
      :map-id="mapId"
      :toolbar-right="toolbarRight"
      :result-features="resultFeatures"
      @attribute-close="() => handleChangeIsAttribute(false)"
      @handle-query-info="handleQueryInfo"
    />

    <!-- 热力图分析 -->
    <MapThermalAnalysis
      v-if="showObject.isHeatMap"
      :route-value="routeValue"
      :map-id="mapId"
      :toolbar-right="toolbarRight"
      @heat-map-close="() => handleChangeIsHeatMap(false)"
    />

    <!--占地分析 -->

    <MapCoverAnalysis
      v-if="showObject.isCoverMap"
      :route-value="routeValue"
      :map-id="mapId"
      :toolbar-right="toolbarRight"
      @cover-map-close="() => handleChangeIsCoverMap(false)"
    />
    <!-- 缓冲区分析 -->
    <MapBufferAnalysis v-if="showObject.isBuffer" :toolbar-right="toolbarRight" @close="handleCHangeIsBuffer" />
    <!-- 测量 -->
    <MapMeasure
      v-show="showObject.isMeasure"
      :toolbar-right="toolbarRight"
      @handle-change-is-measure="handleChangeIsMeasure"
    />
    <!-- 卷帘 -->
    <MapCompare v-if="showObject.isCompare" :map-id="mapId" :route-value="routeValue" />

    <!-- 数据切割 -->
    <MapCutting
      v-if="showObject.isCutting"
      :map-id="mapId"
      :route-value="routeValue"
      :toolbar-right="toolbarRight"
      @cutting-close="() => handleChangeIsCutting(false)"
    />
    <!-- 比例尺 -->
    <div
      v-if="mapRoles.includes('比例尺')"
      class="flex-center"
      :class="`scale-box`"
      :style="{ right: toolbarPosition }"
    >
      <span>{{ scale }}</span>
      <div class="scale-border" />
    </div>
    <div :id="mapId" class="map relative h-full w-full"></div>
    <MapPoints v-if="mapRoles.includes('坐标转换')" />

    <!-- 属性查询结果 -->
    <MapAttributeQuery
      v-if="showObject.resultFeaturesShow"
      class="animate__backInDown"
      :result-features="resultFeatures"
      @handle-close-query-layer="handleCloseQueryLayer"
    />

    <!-- 空间查询 -->
    <MapQueryResultPolygon
      :polygon-show="showObject.resultFeaturesPolygonShow"
      :result-features="resultFeatures"
      @close-query-result-show="handleCloseQueryLayer"
    />
  </div>
</template>

<style scoped lang="scss">
.map-root {
  overflow: hidden;

  .map-tool-top {
    position: fixed;
    top: 111px;
    z-index: 20;
    transition: 1s;
  }

  .map-tool-bottom {
    position: fixed;
    bottom: 50px;
    z-index: 20;
    transition: 1s;
  }
  .tool-item-changesize {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
    width: 50px;
    height: 150px;
    margin-bottom: 10px;
    padding: 5px 0;
    background: rgba(0, 69, 93, 0.6) url('@assets/images/base-map/change-size-bg.png') no-repeat center / 100%;

    img {
      display: block;
      width: 20px;
      height: 20px;
      margin: 0 auto;
      cursor: pointer;
    }

    div {
      color: rgba(201, 226, 250, 1);
      font-size: 14px;
    }
  }

  .tool-item {
    width: 48px;
    height: 48px;
    margin-bottom: 10px;
    cursor: pointer;

    i {
      width: 48px;
      height: 48px;
    }

    img {
      display: block;
      width: 48px;
      height: 48px;
    }
  }

  .scale-box {
    position: absolute;
    bottom: 20px;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 102px;
    height: 34px;
    background-color: rgba(19, 53, 74, 0.7);
    transition: 1s;

    span {
      color: #fff;
      font-weight: 400;
      font-size: 16px;
      line-height: 24px;
      text-align: center;
    }

    // .scale-border {
    //   width: 102px;
    //   height: 6px;
    //   border-right: 2px solid rgb(0, 160, 233);
    //   border-bottom: 4px solid rgb(0, 160, 233);
    //   border-left: 2px solid rgb(0, 160, 233);
    // }
  }

  .layer-item {
    display: flex;
    align-items: center;
    justify-content: center;
    background: url('@/assets/images/base-map/layer-icon-bg.png') no-repeat center/100%;

    img {
      display: block;
      width: 18px;
      height: 18px;
    }
  }
}
</style>
